package vsqlbuilder.gui.diagram;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.List;

import vsqlbuilder.gui.util.KeyController;
import vsqlbuilder.gui.util.MouseController;
import vsqlbuilder.logic.Column;
import vsqlbuilder.logic.Table;
import vsqlbuilder.logic.sql.Query;
import vsqlbuilder.logic.sql.QueryJoin;




public class DiagramController {

	private List<IGshape> elements;
	private DiagramView view;
	private DiagramModel model;
	private Query query;
	

	// Argument are graphic elements list to control
	public DiagramController(List<IGshape> elements) { // (DiagramView view,
		this.elements = elements;
	}

	IGshape getShapeAt(int x, int y) {

		int count = this.elements.size();
		for (int i = count - 1; i >= 0; i--) { //Check for tables
			IGshape shape = this.elements.get(i);
			if (shape.contains(x, y)) {
				return shape;
			}else{ 
			//Check for join link if table was not selected
				if(shape instanceof GTable){
					GTable gt= (GTable) shape;
					for(GAnchorPoint anchor : gt.getAnchorPointsList()){  //Go through all anchor points of GTable
						for(GJoinRelation jr : anchor.getJoinsList()){
							if(jr.contains(x, y)){
								return (IGshape) jr;
							}
						}
					}
				}
			}
		}
		return null;
	}

	public void registerView(DiagramView v) {
		this.view = v;
	}

	public void registerModel(DiagramModel m) {
		this.model = m;
	}

	public void registerQuery(Query query) {
		this.query = query;
	}

	public void registerEvents() {
		// MOUSE events
		MouseController mouseControl = new MouseController() {
			public void mouseClicked(MouseEvent event) {
			}

			public void mouseEntered(MouseEvent event) {
				view.requestFocus(); // [BUG fix #4] Part 3/3 - default
				// focusability for JPanel is false, so
				// you need to include this line to do
				// work keyboard events
			}

			public void mouseExited(MouseEvent event) {
				// TODO [low]: research if there is any way of quit focus from
				// JPanel
				// when the mouse exists control area
			}

			public void mousePressed(MouseEvent event) {
				view.eVmousePressed(event);
			}

			public void mouseReleased(MouseEvent event) {
				view.eVmouseReleased(event);
			}

			public void mouseDragged(MouseEvent event) {
				view.eVmouseDragged(event);
			}

			public void mouseMoved(MouseEvent event) {
			}
		};
		// Register mouse events for the diagram
		view.addMouseListener(mouseControl);
		view.addMouseMotionListener(mouseControl);

		// KEYBOARD EVENTS
		KeyController keyboardControl = new KeyController() {
			public void keyTyped(KeyEvent e) {
			}

			public void keyPressed(KeyEvent e) {
				view.eVkeyPressed(e);
			}

			public void keyReleased(KeyEvent e) {
			}
		};
		// Register keyboard events for the diagram
		view.addKeyListener(keyboardControl);

	}

	public void addTableToQuery(Table table) {
		this.query.addTableToQuery(table);
	}

	public void addColumnToQuery(Column column) {
		this.query.addColumnToQuery(column);
	}

	public void removeColumnFromQuery(Column column) {
		this.query.removeColumnFromQuery(column);
	}

	private void removeTableFromQuery(Table table) {
		this.query.removeTableFromQuery(table);
	}

	// This method remove FIRST SELECTED table from model {is open as option to extend this to all selected tables in a future}
	public void removeTables() {
		this.model.subtractionTable();
		Table temp;
		for (IGshape element : this.elements) {
			if (element.getSelected()) {
				// First remove table from diagram's Logic
				if (element instanceof GTable) {
					temp = (Table) element.getShapeLogic();
					this.removeTableFromQuery(temp);
				}
				// After remove table from graph list to draw in table
				elements.remove(element);
				break; // [BUG FIX#6] if continue iterating over the modified
				// list a exception is throw when remove graphics
				// object.
			}
		}
	}

	public void addJoinLinktoQuery(QueryJoin qj){
		this.query.addJoinToQuery(qj);
	}
	
	public void removeJoinFromQuery(QueryJoin qj){
		this.query.removeJoinFromQuery(qj);
	}
	
	// This method remove FIRST SELECTED join relation from model {is open as option to extend this to all selected tables in a future}
	public void removeJoinLinks(){
		this.model.subtractionJoinRelation();
		//Check every table to find selected join relation and delete it.
		for (IGshape element : this.elements) {
			if(element instanceof GTable){
				GTable gt=(GTable)element;
				for(GAnchorPoint ap : gt.getAnchorPointsList()){
					for(GJoinRelation gjr : ap.getJoinsList()){
						if(gjr.selected){
							gjr.selected=false;
							ap.removeJoinRelation(gjr);
							//TODO [low]: Check-> This process should eliminate query join inside GJoinRelation
							break; //after remove first join exit loops
						}
					}
				}
			}
		}
	}
	
}
